using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using System;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.GamerServices;

namespace Assignment4_Network
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;

        private Texture2D ball;
        private Texture2D padLeft;
        private Texture2D padRight;
        private Texture2D pauseScreen;

        //Ball's velocity
        private Vector2 velocity;

        //Ball's properties
        private Vector2 ballPos;
        private Vector2 ballOrigin;
        private Vector2 ballPosZero;

        //Pads' property
        private Vector2 padPos1;
        private Vector2 padPos2;

        private Vector2 screenDimension;

        private SpriteFont font;
        private SpriteFont consoleFont;

        private float teamAStringLength;
        private float teamBStringLength;

        private string pauseString;
        private Vector2 pausePosition;

        private int scoreA;
        private int scoreB;

        private bool isPause;
        private bool isConsoleActivated;
        //Use to determine which state of the game(Menu, SinglePlayer or Multiplayer)
        private enum SelectedState
        {
            Menu,
            Single,
            Multi
        }
        private SelectedState selectedState = SelectedState.Menu;

        private Color backgroundColor;

        #region CommandLine properties
        private string cmdString = ">";
        private string[] cmdWithArguments;
        private char[] separator = { ' ' };
        private string outputString = ">Welcome to console. What can I help you with?\n>Type 'help' for list of commands\n";
        private Commands cmd;
        private Vector2 cmdStringHeight;
        private int numberOfLine = 2;
        private int numberOfColumn = 1;
        private int numberOfLineTemporary = 1;
        private AnimatedSprite animatedSprite;
        #endregion
        //input wrapper class
        private InputProcessor inputListener;

        #region Networking Properties
        private NetworkSession networkSession;

        private PacketWriter packetWriter = new PacketWriter();
        private PacketReader packetReader = new PacketReader();

        private string errorMessage;

        private const int maxGamers = 2;
        private const int maxLocalGamers = 1;
        #endregion

        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";

            inputListener = new InputProcessor(this);
            Components.Add(inputListener);

            Components.Add(new GamerServicesComponent(this));
        }

        /// <summary>
        /// Allows the game to perform any initialization it needs to before starting to run.
        /// This is where it can query for any required services and load any non-graphic
        /// related content.  Calling base.Initialize will enumerate through any components
        /// and initialize them as well.
        /// </summary>
        protected override void Initialize()
        {
            // TODO: Add your initialization logic here
            isPause = true;
            isConsoleActivated = false;

            velocity = new Vector2(5f);

            scoreA = 0;
            scoreB = 0;


#if WINDOWS
            pauseString = "Game paused. Press Enter to resume";
#elif XBOX
            pauseString="Game paused. Press Start to resume";
#endif


            backgroundColor = Color.CornflowerBlue;

            base.Initialize();

        }

        /// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);

            // TODO: use this.Content to load your game content here
            consoleFont = Content.Load<SpriteFont>("Console");
            cmdStringHeight = new Vector2(0, consoleFont.MeasureString("bdfghjklpqtyA").Y - 2);

            ball = Content.Load<Texture2D>("img/ball");
            padLeft = Content.Load<Texture2D>("img/left");
            padRight = Content.Load<Texture2D>("img/right");

            screenDimension = new Vector2(graphics.GraphicsDevice.Viewport.Width, graphics.GraphicsDevice.Viewport.Height);

            ballOrigin = new Vector2(ball.Width, ball.Height) / 2;

            ballPosZero = screenDimension / 2;
            ballPos = ballPosZero;

            padPos1 = new Vector2(0, screenDimension.Y / 2 - 50);
            padPos2 = new Vector2(screenDimension.X - 20, screenDimension.Y / 2 - 50);

            font = Content.Load<SpriteFont>("font");
            teamAStringLength = font.MeasureString("Team A").X / 2;
            teamBStringLength = font.MeasureString("Team B").X / 2;

            pausePosition = screenDimension / 2 - font.MeasureString(pauseString) / 2;

            CreateRectangle((int)screenDimension.X, (int)screenDimension.Y, out pauseScreen, Color.White);

            Texture2D cursor = Content.Load<Texture2D>("img/cursor");
            animatedSprite = new AnimatedSprite(cursor, 1, 20);
        }

        /// <summary>
        /// UnloadContent will be called once per game and is the place to unload
        /// all content.
        /// </summary>
        protected override void UnloadContent()
        {
            // TODO: Unload any non ContentManager content here
        }

        #region Update
        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {
            // Allows the game to exit
            if (inputListener.isButtonPressed(Buttons.Back, PlayerIndex.One) || inputListener.isKeyPressed(Keys.Escape))
                if (selectedState == SelectedState.Menu)
                    this.Exit();
                else
                {
                    selectedState = SelectedState.Menu;
                    scoreA = 0;
                    scoreB = 0;
                    ballPos = ballPosZero;
                    padPos1 = new Vector2(0, screenDimension.Y / 2 - 50);
                    padPos2 = new Vector2(screenDimension.X - 20, screenDimension.Y / 2 - 50);
                    isPause = true;
                }

            // TODO: Add your update logic here
            switch (selectedState)
            {
                case SelectedState.Menu:
                    UpdateMainMenu();
                    break;
                case SelectedState.Single:
                    UpdateSinglePlayer();
                    break;
                case SelectedState.Multi:
                    UpdateMultiPlayer();
                    break;
            }

            base.Update(gameTime);
        }
        private void UpdateMainMenu()
        {
            if (inputListener.isKeyPressed(Keys.A) || inputListener.isButtonPressed(Buttons.A, PlayerIndex.One))
            {
                selectedState = SelectedState.Single;
            }
            else if (inputListener.isKeyPressed(Keys.B) || inputListener.isButtonPressed(Buttons.B, PlayerIndex.One))
            {
                selectedState = SelectedState.Multi;
            }
        }

        #region Singleplayer Update
        private void UpdateSinglePlayer()
        {
            if (!isConsoleActivated)
            {
                ToggleListener();
                if (!isPause)
                {
#if !XBOX
                    if (inputListener.gamePadConnected[0])
                    {
                        if (inputListener.gamePadConnected[1])
                        {
                            HandlleGamepad(inputListener.getLeftThumbstickValue(PlayerIndex.One).Y, ref padPos1.Y);
                            HandlleGamepad(inputListener.getLeftThumbstickValue(PlayerIndex.Two).Y, ref padPos2.Y);
                        }
                        else
                        {
                            HandlleGamepad(inputListener.getLeftThumbstickValue(PlayerIndex.One).Y, ref padPos1.Y);
                            HanndleKeyboard(ref padPos2.Y, true);
                        }
                    }
                    else
                    {
                        HanndleKeyboard(ref padPos1.Y, false);
                        HanndleKeyboard(ref padPos2.Y, true);
                    }
#else
            if (inputListener.gamePadConnected[1])
            {
                HandlleGamepad(inputListener.getLeftThumbstickValue(PlayerIndex.One).Y, ref padPos1.Y);
                HandlleGamepad(inputListener.getLeftThumbstickValue(PlayerIndex.Two).Y, ref padPos2.Y);
            }
            else
            {
                HandlleGamepad(inputListener.getLeftThumbstickValue(PlayerIndex.One).Y, ref padPos1.Y);
                HandlleGamepad(inputListener.getRightThumbstickValue(PlayerIndex.One).Y, ref padPos2.Y);
            }
#endif

                    UpdateBall();
                }
            }
            else
            {
                isPause = false;
                animatedSprite.Update();
                CommandListener();
            }
        }

        #endregion

        #region Multiplayer Update
        private void UpdateMultiPlayer()
        {
            if (networkSession == null)
            {
                // If we are not in a network session, update the
                // menu screen that will let us create or join one.
                UpdateNetworkMenu();
            }
            else
            {
                // If we are in a network session, update it.
                UpdateNetworkSession();
            }
        }

        /// <summary>
        /// Menu screen provides options to create or join network sessions.
        /// </summary>
        private void UpdateNetworkMenu()
        {
            if (IsActive)
            {
                if (Gamer.SignedInGamers.Count == 0)
                {
                    // If there are no profiles signed in, we cannot proceed.
                    // Show the Guide so the user can sign in.
                    Guide.ShowSignIn(1, false);
                }
                else
                    if (inputListener.isButtonPressed(Buttons.A, PlayerIndex.One) || inputListener.isKeyPressed(Keys.A))
                    {
                        // Create a new session?
                        CreateSession();
                    }
                    else if (inputListener.isButtonPressed(Buttons.B, PlayerIndex.One) || inputListener.isKeyPressed(Keys.B))
                    {
                        // Join an existing session?
                        JoinSession();
                    }
            }
        }
        #region Network Settup
        /// <summary>
        /// Starts hosting a new network session.
        /// </summary>
        private void CreateSession()
        {
            DrawMessage("Creating session...");

            try
            {
                networkSession = NetworkSession.Create(NetworkSessionType.SystemLink,
                                                       maxLocalGamers, maxGamers);

                HookSessionEvents();
            }
            catch (Exception e)
            {
                errorMessage = e.Message;
            }
        }
        /// <summary>
        /// Joins an existing network session.
        /// </summary>
        private void JoinSession()
        {
            DrawMessage("Joining session...");

            try
            {
                // Search for sessions.
                using (AvailableNetworkSessionCollection availableSessions =
                            NetworkSession.Find(NetworkSessionType.SystemLink,
                                                maxLocalGamers, null))
                {
                    if (availableSessions.Count == 0)
                    {
                        errorMessage = "No network sessions found.";
                        return;
                    }

                    // Join the first session we found.
                    networkSession = NetworkSession.Join(availableSessions[0]);

                    HookSessionEvents();
                }
            }
            catch (Exception e)
            {
                errorMessage = e.Message;
            }
        }
        /// <summary>
        /// After creating or joining a network session, we must subscribe to
        /// some events so we will be notified when the session changes state.
        /// </summary>
        private void HookSessionEvents()
        {
            networkSession.GamerJoined += GamerJoinedEventHandler;
            networkSession.SessionEnded += SessionEndedEventHandler;
        }
        /// <summary>
        /// This event handler will be called whenever a new localGamer joins the session.
        /// </summary>
        private void GamerJoinedEventHandler(object sender, GamerJoinedEventArgs e)
        {
            //e.Gamer.Tag = new Player(padPos2.Y, true);
        }
        /// <summary>
        /// Event handler notifies us when the network session has ended.
        /// </summary>
        private void SessionEndedEventHandler(object sender, NetworkSessionEndedEventArgs e)
        {
            errorMessage = e.EndReason.ToString();

            networkSession.Dispose();
            networkSession = null;
        }
        #endregion

        private void UpdateNetworkSession()
        {
            ToggleListener();
            if (!isPause && networkSession.AllGamers.Count == 2)
            {
#if !XBOX
                if (inputListener.gamePadConnected[0])
                {
                    HandlleGamepad(inputListener.getLeftThumbstickValue(PlayerIndex.One).Y, ref padPos1.Y);
                }
                else
                {
                    HanndleKeyboard(ref padPos1.Y, false);
                }
#else
                HandlleGamepad(inputListener.getLeftThumbstickValue(PlayerIndex.One).Y, ref padPos1.Y);
#endif
            }

            foreach (LocalNetworkGamer localGamer in networkSession.LocalGamers)
            {
                UpdateLocalGamer(localGamer);
            }
            // Pump the underlying session object.
            networkSession.Update();

            // Make sure the session has not ended.
            if (networkSession == null)
                return;

            foreach (LocalNetworkGamer localGamer in networkSession.LocalGamers)
            {
                ReadIncomingPackets(localGamer);
            }

            if (!isPause && networkSession.AllGamers.Count == 2)
            {
                UpdateBall();
            }

        }
        /// <summary>
        /// Helper for updating a locally controlled localGamer.
        /// </summary>
        void UpdateLocalGamer(LocalNetworkGamer localGamer)
        {
            //Write the state into a network packet
            
            packetWriter.Write(padPos1.Y);
            packetWriter.Write(scoreA);
            if (networkSession.IsHost)
            {
                packetWriter.Write(isPause);
            }

            // Send the data to everyone in the session
            localGamer.SendData(packetWriter, SendDataOptions.InOrder);
        }
        /// <summary>
        /// Helper for reading incoming network packets.
        /// </summary>
        void ReadIncomingPackets(LocalNetworkGamer localGamer)
        {
            // Keep reading as long as incoming packets are available.
            while (localGamer.IsDataAvailable)
            {
                NetworkGamer sender;

                // Read a single packet from the network.
                localGamer.ReceiveData(packetReader, out sender);

                // Discard packets sent by local gamers: we already know their state!
                if (sender.IsLocal)
                    continue;

                // Read the state of this tank from the network packet.
                
                padPos2.Y = packetReader.ReadSingle();
                scoreB = packetReader.ReadInt32();
                if (!networkSession.IsHost)
                {
                    isPause = packetReader.ReadBoolean();
                }
            }
        }

        #endregion
        private void UpdateBall()
        {

            if (ballPos.X < 20 + ballOrigin.X)
            {
                if (ballPos.Y < padPos1.Y + 100 + ballOrigin.Y && ballPos.Y > padPos1.Y - ballOrigin.Y)
                {
                    ballPos.X = 20 + ballOrigin.X;
                }
                else
                {
                    scoreB++;
                    ballPos = ballPosZero;
                }
                velocity.X *= -1;
            }
            if (ballPos.X > screenDimension.X - 20 - ballOrigin.X)
            {
                if (ballPos.Y < padPos2.Y + 100 + ballOrigin.Y && ballPos.Y > padPos2.Y - ballOrigin.Y)
                {
                    ballPos.X = screenDimension.X - ballOrigin.X - 20;
                }
                else
                {
                    scoreA++;
                    ballPos = ballPosZero;
                }
                velocity.X *= -1;
            }


            if (ballPos.Y < ballOrigin.Y || ballPos.Y > screenDimension.Y - ballOrigin.Y)
                velocity.Y *= -1;
            ballPos += velocity;

        }
        public void ToggleListener()
        {
            if (selectedState == SelectedState.Single)
            {
                //toggle pause
                if (inputListener.isKeyPressed(Keys.Enter) || inputListener.isButtonPressed(Buttons.Start, PlayerIndex.One) || inputListener.isButtonPressed(Buttons.Start, PlayerIndex.Two))
                {
                    isPause = !isPause;
                }

                //togle command
                if (inputListener.isKeyPressed(Keys.C))
                {
                    outputString = ">Welcome to console. What can I help you with?\n>Type 'help' for list of commands\n";
                    isConsoleActivated = !isConsoleActivated;
                }
            }
            else if (selectedState == SelectedState.Multi)
            {
                if (networkSession.IsHost && (inputListener.isKeyPressed(Keys.Enter) || inputListener.isButtonPressed(Buttons.Start, PlayerIndex.One)))
                {
                    isPause = !isPause;
                }
            }
        }
        #endregion

        #region Draw
        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(backgroundColor);

            // TODO: Add your drawing code here

            switch (selectedState)
            {
                case SelectedState.Menu:
                    DrawMenu();
                    break;
                case SelectedState.Single:
                    DrawSinglePlayer();
                    break;
                case SelectedState.Multi:
                    DrawMultiPlayer();
                    break;
            }
            base.Draw(gameTime);
        }

        private void DrawMenu()
        {
            string message = "A = Single Player\n" +
                       "B = Multi Player";
            spriteBatch.Begin();
            spriteBatch.DrawString(font, message, new Vector2(161, 161), Color.Black);
            spriteBatch.DrawString(font, message, new Vector2(160, 160), Color.White);
            spriteBatch.End();
        }

        private void DrawSinglePlayer()
        {
            spriteBatch.Begin();
            if (!isConsoleActivated)
            {
                spriteBatch.Draw(padLeft, padPos1, Color.White);
                spriteBatch.Draw(padRight, padPos2, Color.White);
                spriteBatch.Draw(ball, ballPos, null, Color.White, 0, ballOrigin, 1, SpriteEffects.None, 0);
                spriteBatch.DrawString(font, "Team A\n   " + scoreA, new Vector2(screenDimension.X / 4 - teamAStringLength, 10), Color.Cornsilk);
                spriteBatch.DrawString(font, "Team B\n   " + scoreB, new Vector2(screenDimension.X * 3 / 4 - teamBStringLength, 10), Color.Cornsilk);

                if (isPause)
                {
                    spriteBatch.Draw(pauseScreen, Vector2.Zero, Color.White * 0.5f);
                    spriteBatch.DrawString(font, pauseString, pausePosition, Color.Black);
                }
            }
            else
            {
                spriteBatch.Draw(pauseScreen, Vector2.Zero, Color.White);
                animatedSprite.Draw(spriteBatch, new Vector2(9 * numberOfColumn, (cmdStringHeight * (numberOfLine + numberOfLineTemporary - 0.2f)).Y));
                spriteBatch.DrawString(consoleFont, outputString, Vector2.Zero, Color.Black);
                spriteBatch.DrawString(consoleFont, cmdString, cmdStringHeight * numberOfLine, Color.Black);
            }
            spriteBatch.End();
        }

        private void DrawMultiPlayer()
        {
            if (networkSession == null)
            {
                // If we are not in a network session, draw the
                // menu screen that will let us create or join one.
                DrawNetworkMenu();
            }
            else
            {
                // If we are in a network session, draw it.
                DrawNetworkSession();
            }
        }
        /// <summary>
        /// Draws the startup screen used to create and join network sessions.
        /// </summary>
        private void DrawNetworkMenu()
        {
            string message = string.Empty;

            if (!string.IsNullOrEmpty(errorMessage))
                message += "Error:\n" + errorMessage.Replace(". ", ".\n") + "\n\n";

            message += "A = create session\n" +
                       "B = join session";

            spriteBatch.Begin();

            spriteBatch.DrawString(font, message, new Vector2(161, 161), Color.Black);
            spriteBatch.DrawString(font, message, new Vector2(160, 160), Color.White);

            spriteBatch.End();
        }
        /// <summary>
        /// Draws the state of an active network session.
        /// </summary>
        private void DrawNetworkSession()
        {
            spriteBatch.Begin();
            if (networkSession.AllGamers.Count == 2)
            {
                spriteBatch.Draw(padLeft, padPos1, Color.White);
                spriteBatch.Draw(padRight, padPos2, Color.White);
                spriteBatch.Draw(ball, ballPos, null, Color.White, 0, ballOrigin, 1, SpriteEffects.None, 0);
                spriteBatch.DrawString(font, networkSession.LocalGamers[0].Gamertag + ((networkSession.IsHost) ? "(host)" : "") + "\n   " + scoreA, new Vector2(screenDimension.X / 4 - teamAStringLength, 10), Color.Cornsilk);
                spriteBatch.DrawString(font, networkSession.RemoteGamers[0].Gamertag + ((networkSession.IsHost) ? "" : "(host)") + "\n   " + scoreB, new Vector2(screenDimension.X * 3 / 4 - teamBStringLength, 10), Color.Cornsilk);
                if (isPause)
                {
                    spriteBatch.Draw(pauseScreen, Vector2.Zero, Color.White * 0.5f);
                    spriteBatch.DrawString(font, pauseString, pausePosition, Color.Black);
                }
            }
            else
                spriteBatch.DrawString(font, "Waiting for opponent...", pausePosition, Color.Black);
            spriteBatch.End();
        }

        /// <summary>
        /// Helper draws notification messages before calling blocking network methods.
        /// </summary>
        private void DrawMessage(string message)
        {
            if (!BeginDraw())
                return;

            GraphicsDevice.Clear(Color.CornflowerBlue);

            spriteBatch.Begin();

            spriteBatch.DrawString(font, message, new Vector2(161, 161), Color.Black);
            spriteBatch.DrawString(font, message, new Vector2(160, 160), Color.White);

            spriteBatch.End();

            EndDraw();
        }

        #endregion

        #region HandleInputs
        private void HandlleGamepad(float stickY, ref float yPos)
        {
            if (yPos >= 0 && yPos <= screenDimension.Y - 100)
            {
                yPos -= stickY * 5;
            }
            yPos = (yPos < 0) ? 0 : yPos;
            yPos = (yPos > screenDimension.Y - 100) ? screenDimension.Y - 100 : yPos;
        }
        private void HanndleKeyboard(ref float yPos, bool isPlayer2)
        {
            if (isPlayer2)
            {
                if (yPos > 0 && inputListener.isKeyDown(Keys.Up))
                {
                    yPos -= 5;
                }
                yPos = (yPos < 0) ? 0 : yPos;
                if (yPos < screenDimension.Y - 100 && inputListener.isKeyDown(Keys.Down))
                {
                    yPos += 5;
                }
                yPos = (yPos > screenDimension.Y - 100) ? screenDimension.Y - 100 : yPos;
            }
            else
            {
                if (yPos > 0 && inputListener.isKeyDown(Keys.W))
                {
                    yPos -= 5;
                }
                yPos = (yPos < 0) ? 0 : yPos;
                if (yPos < screenDimension.Y - 100 && inputListener.isKeyDown(Keys.S))
                {
                    yPos += 5;
                }
                yPos = (yPos > screenDimension.Y - 100) ? screenDimension.Y - 100 : yPos;
            }
        }
        #endregion

        #region Command
        public void CommandListener()
        {
            ProcessString();
            foreach (Keys presskey in Keyboard.GetState().GetPressedKeys())
            {
                if (inputListener.isKeyPressed(presskey))
                {
                    switch (presskey)
                    {
                        case Keys.Space:
                            cmdString += " ";
                            numberOfColumn++;
                            break;
                        case Keys.Back:
                            if (cmdString.Length > 1)
                            {
                                cmdString = cmdString.Remove(cmdString.Length - 1);
                                numberOfColumn--;
                            }
                            break;
                        case Keys.Enter:
                            numberOfColumn = 1;
                            cmdWithArguments = cmdString.Split(separator, StringSplitOptions.RemoveEmptyEntries);
                            try
                            {
                                cmd = (Commands)Enum.Parse(typeof(Commands), cmdWithArguments[0].TrimStart('>'), true);
                            }
                            catch (ArgumentException)
                            {
                                cmd = Commands.error;
                            }
                            if (cmdWithArguments.Length == 2 && cmdWithArguments[0].Equals(">bgcolor"))
                            {
                                switch (cmdWithArguments[1][0])
                                {
                                    case 'r':
                                        backgroundColor = Color.Red;
                                        outputString += cmdString + ":Background changed to RED\n";
                                        break;
                                    case 'b':
                                        backgroundColor = Color.Blue;
                                        outputString += cmdString + ":Background changed to BLUE\n";
                                        break;
                                    case 'g':
                                        backgroundColor = Color.Green;
                                        outputString += cmdString + ":Background changed to GREEN\n";
                                        break;
                                    case 'd':
                                        backgroundColor = Color.CornflowerBlue;
                                        outputString += cmdString + ":Background changed to DEFAULT\n";
                                        break;
                                    default:
                                        outputString += cmdString + ":invalid argument\n";
                                        break;
                                }
                                numberOfLine++;
                            }
                            else
                                switch (cmd)
                                {
                                    case Commands.exit:
                                        isConsoleActivated = false;
                                        numberOfLine = 2;
                                        isPause = true;
                                        break;
                                    case Commands.cls:
                                        outputString = "";
                                        numberOfLine = 0;
                                        break;
                                    case Commands.help:
                                        outputString += ">List of commands:\ncls:clear console screen\nexit: exit console\nbgcolor [value]: change background color value\n [value]=r|g|b|d\n  r for red\n  g for green\n  b for blue\n  d for default\nquit:exit game\n";
                                        numberOfLine += 10;
                                        break;
                                    case Commands.quit:
                                        this.Exit();
                                        break;
                                    case Commands.error:
                                        outputString += cmdString + ":invalid command\n";
                                        numberOfLine += numberOfLineTemporary;
                                        break;
                                }
                            numberOfLineTemporary = 1;
                            cmdString = ">";
                            break;
                        default:
                            if (presskey >= Keys.A && presskey <= Keys.Z)
                            {
                                cmdString += Enum.GetName(typeof(Keys), presskey);
                                numberOfColumn++;
                            }
                            break;
                    }
                }
            } cmdString = cmdString.ToLower();
        }

        public void ProcessString()
        {
            if (numberOfLine + numberOfLineTemporary - 1 > 24)
            {
                for (int i = 24; i < numberOfLine + numberOfLineTemporary - 1; i++)
                    outputString = outputString.Substring(outputString.IndexOf("\n") + 1);
                numberOfLine = 24 - (numberOfLineTemporary - 1);
            }
            if (numberOfColumn >= 80)
            {
                cmdString += '\n';
                numberOfLineTemporary++;
                numberOfColumn = 0;
            }
        }
        #endregion

        public void CreateRectangle(int width, int height, out Texture2D rectangleTexture, Color color)
        {
            // create the rectangle texture, ,but it will have no color! lets fix that
            rectangleTexture = new Texture2D(GraphicsDevice, width, height, false, SurfaceFormat.Color);

            // set the color to the amount of pixels
            Color[] colors = new Color[width * height];

            // loop through all the colors setting them to whatever values we want
            for (int i = 0; i < colors.Length; i++)
            {
                colors[i] = color;
            }

            // set the color data on the texture
            rectangleTexture.SetData(colors);

        }


    }
}
